/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using System.Threading.Tasks;
using System;

namespace NetProtocol.Server {
	/// <summary>
	/// 邮件模块
	/// module : mail
	/// </summary>
	public interface SNetMail : INetServerModule {
		Dictionary<int, MessageHandler> INetServerModule.GetModuleFunction()
        {	
            return new()
            {
                { NetMessageId.mail_getMails, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.mail_getMails, "Recv->" + data.ToString());
#endif
		                GetMailsRequest _data = (GetMailsRequest)data;
						return CS_getMails(session, _data.mailType);
		            } 
            	},
                { NetMessageId.mail_readMail, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.mail_readMail, "Recv->" + data.ToString());
#endif
		                ReadMailRequest _data = (ReadMailRequest)data;
						return CS_readMail(session, _data.mailId);
		            } 
            	},
                { NetMessageId.mail_pickUp, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.mail_pickUp, "Recv->" + data.ToString());
#endif
		                PickUpRequest _data = (PickUpRequest)data;
						return CS_pickUp(session, _data.mailIdList);
		            } 
            	},
                { NetMessageId.mail_deleteMail, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.mail_deleteMail, "Recv->" + data.ToString());
#endif
		                DeleteMailRequest _data = (DeleteMailRequest)data;
						return CS_deleteMail(session, _data.mailIdList);
		            } 
            	},
            };
        }
        
        Dictionary<int, Func<IReceiveMessage>> INetServerModule.GetModuleRequest() 
        {
	        return new ()
	        {
	        	{NetMessageId.mail_getMails, ()=> new GetMailsRequest()},
	        	{NetMessageId.mail_readMail, ()=> new ReadMailRequest()},
	        	{NetMessageId.mail_pickUp, ()=> new PickUpRequest()},
	        	{NetMessageId.mail_deleteMail, ()=> new DeleteMailRequest()},
	        };
	    }
        
#region Server-side Interface
		/// <summary>
        /// 得到邮件列表
        /// </summary>
	    protected GetMailsResult CS_getMails(ISession session, int mailType);
		/// <summary>
        /// 阅读邮件
        /// </summary>
	    protected ReadMailResult CS_readMail(ISession session, long mailId);
		/// <summary>
        /// 领取附件
        /// </summary>
	    protected PickUpResult CS_pickUp(ISession session, List<long> mailIdList);
		/// <summary>
        /// 删除邮件
        /// </summary>
	    protected DeleteMailResult CS_deleteMail(ISession session, List<long> mailIdList);
#endregion
#region Client-side Interface
		/// <summary>
        /// 
        /// </summary>
        public GetMailsResult SC_getMailsResult(Task<GetMailsResult> future){return new GetMailsResult(future);}
        public GetMailsResult SC_getMailsResult(int code, List<MailSimplePOD> mailList){return new GetMailsResult(code, mailList);}
        public GetMailsResult SC_getMailsResult(int code){return new GetMailsResult(code);}
		/// <summary>
        /// 
        /// </summary>
        public ReadMailResult SC_readMailResult(Task<ReadMailResult> future){return new ReadMailResult(future);}
        public ReadMailResult SC_readMailResult(int code, MailPOD mail){return new ReadMailResult(code, mail);}
        public ReadMailResult SC_readMailResult(int code){return new ReadMailResult(code);}
		/// <summary>
        /// getItems=获得的物品
        /// </summary>
        public PickUpResult SC_pickUpResult(Task<PickUpResult> future){return new PickUpResult(future);}
        public PickUpResult SC_pickUpResult(int code, List<long> pickedList, List<ItemShowPOD> getItems){return new PickUpResult(code, pickedList, getItems);}
        public PickUpResult SC_pickUpResult(int code){return new PickUpResult(code);}
		/// <summary>
        /// 
        /// </summary>
        public DeleteMailResult SC_deleteMailResult(Task<DeleteMailResult> future){return new DeleteMailResult(future);}
        public DeleteMailResult SC_deleteMailResult(int code, List<long> deletedList){return new DeleteMailResult(code, deletedList);}
        public DeleteMailResult SC_deleteMailResult(int code){return new DeleteMailResult(code);}
		/// <summary>
        /// 通知新邮件数量(普通邮件)
        /// </summary>
		public bool SC_notifyNewMail(ISession session, int newMailCount){
	        return NetProtocolHelper.SendMessage(session, new NotifyNewMail(newMailCount));
	    }
	    public void SC_notifyNewMail_Broadcast(List<ISession> sessions, int newMailCount){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyNewMail(newMailCount));
	    }
#endregion

#region Messages
	public class GetMailsResult : MessageResult {
	    private List<MailSimplePOD> mailList;
	    public GetMailsResult(Task<GetMailsResult> future): base(future) { }
		public GetMailsResult(int code): base(code) { }
		public new GetMailsResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal GetMailsResult(int code, List<MailSimplePOD> mailList){
	        this.code = code;
	        this.mailList = mailList == null ? null : new (mailList);
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<GetMailsResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.mail_getMailsResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_getMailsResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_list_pod(mailList);
			return si_p;
		}
		public override string ToString() {
    		return "Mail.SC_getMailsResult { "
			+ "code="
			+ code
			+ ", mailList="
			+ mailList.ToString<MailSimplePOD>()
			+" }";
		}
	}
	public class ReadMailResult : MessageResult {
	    private MailPOD mail;
	    public ReadMailResult(Task<ReadMailResult> future): base(future) { }
		public ReadMailResult(int code): base(code) { }
		public new ReadMailResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal ReadMailResult(int code, MailPOD mail){
	        this.code = code;
	        this.mail = mail;
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<ReadMailResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.mail_readMailResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_readMailResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_pod(mail);
			return si_p;
		}
		public override string ToString() {
    		return "Mail.SC_readMailResult { "
			+ "code="
			+ code
			+ ", mail="
			+ mail
			+" }";
		}
	}
	public class PickUpResult : MessageResult {
	    private List<long> pickedList;
	    private List<ItemShowPOD> getItems;
	    public PickUpResult(Task<PickUpResult> future): base(future) { }
		public PickUpResult(int code): base(code) { }
		public new PickUpResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal PickUpResult(int code, List<long> pickedList, List<ItemShowPOD> getItems){
	        this.code = code;
	        this.pickedList = pickedList == null ? null : new (pickedList);
	        this.getItems = getItems == null ? null : new (getItems);
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<PickUpResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.mail_pickUpResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_pickUpResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_list_long(pickedList);	
			_out.Write_list_pod(getItems);
			return si_p;
		}
		public override string ToString() {
    		return "Mail.SC_pickUpResult { "
			+ "code="
			+ code
			+ ", pickedList="
			+ pickedList.ToString<long>()
			+ ", getItems="
			+ getItems.ToString<ItemShowPOD>()
			+" }";
		}
	}
	public class DeleteMailResult : MessageResult {
	    private List<long> deletedList;
	    public DeleteMailResult(Task<DeleteMailResult> future): base(future) { }
		public DeleteMailResult(int code): base(code) { }
		public new DeleteMailResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal DeleteMailResult(int code, List<long> deletedList){
	        this.code = code;
	        this.deletedList = deletedList == null ? null : new (deletedList);
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<DeleteMailResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.mail_deleteMailResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_deleteMailResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_list_long(deletedList);	
			return si_p;
		}
		public override string ToString() {
    		return "Mail.SC_deleteMailResult { "
			+ "code="
			+ code
			+ ", deletedList="
			+ deletedList.ToString<long>()
			+" }";
		}
	}
	public class NotifyNewMail : MessageNotify {
		private int newMailCount;
		public NotifyNewMail(int newMailCount) {
		    this.newMailCount = newMailCount;
		}
		public override int GetMessageId() {return NetMessageId.mail_notifyNewMail;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mail_notifyNewMail;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(newMailCount);
			return si_p;
		}
		public override string ToString() {
			return "Mail.SC_notifyNewMail { "
			+ "newMailCount="
			+ newMailCount
			+" }";
		}
	}
	private class GetMailsRequest : IReceiveMessage
    {
		internal int mailType;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            mailType = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.mail_getMails; }
        public override string ToString()
        {
            return "Mail.getMails"+ ", mailType="+ mailType;
        }
    }
	private class ReadMailRequest : IReceiveMessage
    {
		internal long mailId;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            mailId = _in.HasRemaining() ? _in.Read_long() : default;
		}
        public int GetMessageId() { return NetMessageId.mail_readMail; }
        public override string ToString()
        {
            return "Mail.readMail"+ ", mailId="+ mailId;
        }
    }
	private class PickUpRequest : IReceiveMessage
    {
		internal List<long> mailIdList;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            mailIdList = _in.HasRemaining() ? _in.Read_list_long() : default;
		}
        public int GetMessageId() { return NetMessageId.mail_pickUp; }
        public override string ToString()
        {
            return "Mail.pickUp"+ ", mailIdList="+ mailIdList.ToString<long>();
        }
    }
	private class DeleteMailRequest : IReceiveMessage
    {
		internal List<long> mailIdList;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            mailIdList = _in.HasRemaining() ? _in.Read_list_long() : default;
		}
        public int GetMessageId() { return NetMessageId.mail_deleteMail; }
        public override string ToString()
        {
            return "Mail.deleteMail"+ ", mailIdList="+ mailIdList.ToString<long>();
        }
    }
	}
#endregion
}